=begin pod :kind("Language") :subkind("Language") :category("tutorial")

=TITLE Modules

=SUBTITLE How to create, use, and distribute Raku modules

=head1 Creating and using modules

A module is usually a source file or set of source files that expose Raku
constructs N<Technically a module is a set of I<compunits> which are usually
files but could come from anywhere as long as there is a I<compunit repository>
that can provide it. See L<S11|https://design.raku.org/S11.html>.>.

Modules are typically packages (L<classes|/language/objects#Classes>,
L<roles|/language/objects#Roles>, L<grammars|/type/Grammar>),
L<subroutines|/language/functions>, and sometimes
L<variables|/language/variables>. In Raku I<module> can also refer to a type of
package declared with the C<module> keyword (see L<Module
Packages|/language/module-packages> and the examples below) but here we mostly
mean "module" as a set of source files in a namespace.

=head2 Looking for and installing modules.

L<C<zef>|https://github.com/ugexe/zef> is the application used for installing
modules in Raku. Modules are listed in
L<the Raku ecosystem|https://modules.raku.org> and can be searched there or
from the command line using C<zef search>:

=for code :lang<shell>
zef search WWW

will return a list of modules that includes WWW in their name, for
instance. Then,

=for code :lang<shell>
zef install WWW

will install the module with that particular name, if it is not already
installed N<If it's installed, it will reinstall only if the version of
the module is newer than the one installed>.


=head2 Basic structure

Module distributions (in the I<set of related source files> sense) in Raku
have the same structure as any distribution in the Perl family of languages:
there is a main project directory containing a C<README> and a C<LICENSE> file,
a C<lib> directory for the source files, which may be individually referred to
as modules and/or may themselves define modules with the C<module> keyword N<As
L<synopsis S11|https://design.raku.org/S11.html#Units> says: Confusing? Yes it
is.> , a C<t> directory for tests, and possibly a C<bin> directory for
executable programs and scripts.

Source files generally use the C<.rakumod> extension, and scripts or
executables use the C<.raku>. Test files use the C<.rakutest> (or C<.t>)
extension. Files which contain documentation use the C<.rakudoc> extension N«The
old C<.p6> (or C<.pl6>), C<.pm6> (or C<.pm> which is also supported, but
discouraged) and C<.pod6> extensions will continue to be supported for 6.e
and marked as B<deprecated> in 6.f».

X<|compunit>
=head1 Loading and basic importing

Loading a module makes the packages in the same namespace declared
within available in the file scope of the loader. Importing from a
module makes the symbols exported available in the lexical scope of
the importing statement.

=head2 X<C<need>>

C<need> loads a C<compunit> at compile time.

=for code :skip-test<needs dummy module>
need MyModule;

Any packages in the namespace defined within will also be available.

=begin code :solo
# MyModule.rakumod
unit module MyModule;

class Class {}
=end code

C<MyModule::Class> will be defined when C<MyModule> is loaded, and you can use
it directly employing its fully qualified name (FQN). Classes and other types
defined that way are not automatically exported; you will need to explicitly
export it if you want to use it by its short name:

=begin code :solo
# MyModule.rakumod
unit module MyModule;

class Class is export {}
=end code

And then

=begin code :skip-test<needs dummy module>
use MyModule;

my $class = Class.new();
say $class.raku;
=end code

=head2 X<C<use>>

C<use> loads and then imports from a compunit at compile time. It will look for
files that end in C<.rakumod>. See L<here|/language/modules#Finding_installed_modules>
for where the runtime will look for modules.

=for code :skip-test<needs dummy module>
use MyModule;

This is equivalent to:

=begin code :allow<L> :skip-test<needs dummy module>
L<need|/language/modules#need> MyModule;
import MyModule;
=end code

See also
L<selective importing|/language/modules#Exporting_and_selective_importing>
to restrict what you import.

=head2 X<C<require>>

C<require> loads a compunit and imports definite symbols at runtime.

    say "loading MyModule";
    require MyModule;

The compunit name can be in a runtime variable if you put it inside an
indirect lookup.

    my $name = 'MyModule';
    require ::($name);

The symbols provided by the loaded module will not be imported into the
current scope. You may use
L<dynamic lookup|/language/packages#index-entry-::()> or
L<dynamic subsets|/language/typesystem#subset> to use them by providing
the fully qualified name of a symbol, for instance:

    require ::("Test");
    my &mmk = ::("Test::EXPORT::DEFAULT::&ok");
    mmk('oi‽'); # OUTPUT: «ok 1 - ␤»

The FQN of C<ok> is C<Test::EXPORT::DEFAULT::&ok>. We are aliasing it to
C<mmk> so that we can use that symbol provided by C<Test> in the current
scope.

To import symbols you must define them at compile time. B<NOTE:>
C<require> is lexically scoped:

    sub do-something {
       require MyModule <&something>;
       say ::('MyModule'); # MyModule symbol exists here
       something() # &something will be defined here
    }
    say ::('MyModule'); # This will NOT contain the MyModule symbol
    do-something();
    # &something will not be defined here

If C<MyModule> doesn't export C<&something> then C<require> will fail.

A C<require> with compile-time symbol will install a placeholder
C<package> that will be updated to the loaded module, class, or package.
Note that the placeholder will be kept, B<even if require failed to load
the module.> This means that checking if a module loaded like this is
wrong:

    # *** WRONG: ***
    try require Foo;
    if ::('Foo') ~~ Failure { say "Failed to load Foo!"; }
    # *** WRONG: ***

As the compile-time installed package causes C<::('Foo')> to never be
a C<Failure>. The correct way is:

    # Use return value to test whether loading succeeded:
    (try require Foo) === Nil and say "Failed to load Foo!";

    # Or use a runtime symbol lookup with require, to avoid compile-time
    # package installation:
    try require ::('Foo');
    if ::('Foo') ~~ Failure {
        say "Failed to load Foo!";
    }

In the current (6.d) version of the language, C<require>d symbols are no longer
transitively exposed, which means that you need to import symbols from the
module they were originally declared, not from the module where they have
been imported.

=head2 Lexical module loading

Raku takes great care to avoid global state, i.e. whatever you do in
your module, it should not affect other code. For instance, that's why
subroutine definitions are lexically (C<my>) scoped by default. If you want
others to see them, you need to explicitly make them C«our» scoped or export
them.

Classes are exported by default on the assumption that loading a module will not
be of much use when you cannot access the classes it contains. Loaded classes
are thus registered only in the scope which loaded them in the first place
N<This change was introduced in late 2016. If you are using versions older than
this, behavior will be different>. This means that we will have to C<use> a
class in every scope in which we actually employ it.

=for code :skip-test<needs dummy module>
use Foo;           # Foo has "use Bar" somewhere.
use Bar;
my $foo = Foo.new;
my $bar = Bar.new;

=head2 Exporting and selective importing

=head3 is export

Packages, subroutines, variables, constants, and enums are exported by marking
them with the L<is export|/routine/is export> trait (also note the tags available for indicating
authors and versions).

    =begin code :solo
    unit module MyModule:ver<1.0.3>:auth<John Hancock (jhancock@example.com)>;
    our $var is export = 3;
    sub foo is export { ... };
    constant FOO is export = "foobar";
    enum FooBar is export <one two three>;

    # for multi methods, if you declare a proto you
    # only need to mark the proto with is export
    proto sub quux(Str $x, |) is export { * };
    multi sub quux(Str $x) { ... };
    multi sub quux(Str $x, $y) { ... };

    # for multi methods, you only need to mark one with is export
    # but the code is most consistent if all are marked
    multi sub quux(Str $x) is export { ... };
    multi sub quux(Str $x, $y) is export { ... };

    # Packages like classes can be exported too
    class MyClass is export {};

    # If a subpackage is in the namespace of the current package
    # it doesn't need to be explicitly exported
    class MyModule::MyClass {};
    =end code

As with all traits, if applied to a routine, C«is export» should appear after
any argument list.

    =begin code :solo
    sub foo(Str $string) is export { ... }
    =end code

You can pass named parameters to C<is export> to group symbols for exporting
so that the importer can pick and choose. There are three predefined
tags: C<ALL>, C<DEFAULT> and C<MANDATORY>.

    =begin code :solo
    # lib/MyModule.rakumod
    unit module MyModule;
    sub bag        is export             { ... }
    # objects with tag ':MANDATORY' are always exported
    sub pants      is export(:MANDATORY) { ... }
    sub sunglasses is export(:day)       { ... }
    sub torch      is export(:night)     { ... }
    sub underpants is export(:ALL)       { ... }
    =end code

    =begin code :skip-test<needs dummy module>
    # main.raku
    use lib 'lib';
    use MyModule;          # bag, pants
    use MyModule :DEFAULT; # the same
    use MyModule :day;     # pants, sunglasses
    use MyModule :night;   # pants, torch
    use MyModule :ALL;     # bag, pants, sunglasses, torch, underpants
    =end code

B<Note>: there currently is no way for the user to import a single
object if the module author hasn't made provision for that, and it is
not an easy task at the moment (see
L<RT #127305|https://github.com/Raku/old-issue-tracker/issues/5063>).
One way
the author can provide such access is to give each C<export> trait its
own unique tag. (And the tag can be the object name!). Then the user can
either (1) import all objects:

=begin code :skip-test<needs dummy module>
use Foo :ALL;
=end code

or (2) import one or more objects selectively:

    =begin code :skip-test<needs dummy module>
    use Foo :bar, :s5;
    =end code

Notes:

1. The C<:MANDATORY> tag on an exported sub ensures it will be exported
no matter whether the using program adds any tag or not.

2. All exported subs without an explicit tag are implicitly C<:DEFAULT>.

3. The space after the module name and before the tag is mandatory.

4. Multiple import tags may be used (separated by commas).  For example:

    =begin code :skip-test<needs dummy module>
    # main.raku
    use lib 'lib';
    use MyModule :day, :night; # pants, sunglasses, torch
    =end code

5. Multiple tags may be used in the C<export> trait, but they must
   all be separated by either commas, or whitespace, but not both.

   =begin code :solo
   sub foo() is export(:foo :s2 :net) {}
   sub bar() is export(:bar, :s3, :some) {}
   =end code

=head3 UNIT::EXPORT::*

Beneath the surface, C<is export> is adding the symbols to a C<UNIT>
scoped package in the C<EXPORT> namespace. For example, C<is
export(:FOO)> will add the target to the C<UNIT::EXPORT::FOO>
package. This is what Raku is really using to decide what to import.

    =begin code :solo
    unit module MyModule;

    sub foo is export { ... }
    sub bar is export(:other) { ... }
    =end code

Is the same as:

    =begin code :solo
    unit module MyModule;

    my package EXPORT::DEFAULT {
        our sub foo { ... }
    }

    my package EXPORT::other {
        our sub bar { ... }
    }
    =end code

For most purposes, C<is export> is sufficient but the C<EXPORT>
packages are useful when you want to produce the exported symbols
dynamically. For example:

    =begin code :solo
    # lib/MyModule.rakumod
    unit module MyModule;

    my package EXPORT::DEFAULT {
       for <zero one two three four>.kv -> $number, $name {
          for <sqrt log> -> $func {
             OUR::{'&' ~ $func ~ '-of-' ~ $name } := sub { $number."$func"() };
          }
       }
    }

    =end code

    =begin code :skip-test<needs dummy module>
    # main.raku
    use MyModule;
    say sqrt-of-four; # OUTPUT: «2␤»
    say log-of-zero;  # OUTPUT: «-Inf␤»
    =end code

X<|sub EXPORT>
=head3 EXPORT

You can export arbitrary symbols with an C<EXPORT> sub. C<EXPORT>
must return a L<Map|/type/Map>, where the keys are the symbol names and
the values are the desired values. The names should include the sigil
(if any) for the associated type.

=begin code :solo
# lib/MyModule.rakumod

class MyModule::Class { }

sub EXPORT {
    Map.new:
      '$var'      => 'one',
      '@array'    => <one two three>,
      '%hash'     => %( one => 'two', three => 'four' ),
      '&doit'     => sub { say 'Greetings from exported sub' },
      'ShortName' => MyModule::Class
}
=end code

Which is going to be used from this main file:

=begin code :skip-test<needs dummy module>
# main.raku
use lib 'lib';
use MyModule;
say $var;          # OUTPUT: «one␤»
say @array;        # OUTPUT: «(one two three)␤»
say %hash;         # OUTPUT: «{one => two, three => four}␤»
doit();            # OUTPUT: «Greetings from exported sub␤»
say ShortName.new; # OUTPUT: «MyModule::Class.new␤»
=end code

Please note that C<EXPORT> can't be declared inside a
L<package|/language/packages> because it is part of the compunit rather than the
package.

Whereas C<UNIT::EXPORT> packages deal with the named parameters passed to
C<use>, the C<EXPORT> sub handles positional parameters. If you pass positional
parameters to C<use>, they will be passed to C<EXPORT>. If a positional is
passed, the module no longer exports default symbols. You may still import them
explicitly by passing C<:DEFAULT> to C<use> along with your positional
parameters.

=begin code
# lib/MyModule

class MyModule::Class {}

sub EXPORT($short_name?) {
    Map.new: do $short_name => MyModule::Class if $short_name
}

sub always is export(:MANDATORY) { say "works" }

#import with :ALL or :DEFAULT to get
sub shy is export { say "you found me!" }
=end code

Used from this main program

=begin code :skip-test<needs dummy module>
# main.raku
use lib 'lib';
use MyModule 'foo';
say foo.new(); # OUTPUT: «MyModule::Class.new␤»

always();      # OK   - is imported
shy();         # FAIL - «shy used at line 8. Did you mean 'say'?»
=end code

You can combine C<EXPORT> with type captures for interesting effect. This
example creates a C<?> postfix which will only work on L<Cool|/type/Cool>s;
please note that, by using C<$_> as an argument, we don't need to use a
variable in the routine body and use just C<.so>, acting by default on the
topic variable.

=begin code
# lib/MakeQuestionable.rakumod
sub EXPORT(::Questionable) {
    my multi postfix:<?>(Questionable $_) { .so };
    Map.new: '&postfix:<?>' => &postfix:<?>,
}
=end code

Which is used from here:

=begin code :skip-test<needs dummy module>
use lib 'lib';
use MakeQuestionable Cool;
say ( 0?, 1?, {}?, %( a => "b" )? ).join(' '); # OUTPUT: «False True False True␤»
=end code

=head2 Introspection

To list exported symbols of a module first query the export tags supported by
the module.

    use URI::Escape;
    say URI::Escape::EXPORT::.keys;
    # OUTPUT: «(DEFAULT ALL)␤»

Then use the tag you like and pick the symbol by its name.

    say URI::Escape::EXPORT::DEFAULT::.keys;
    # OUTPUT: «(&uri-escape &uri-unescape &uri_escape &uri_unescape)␤»
    my &escape-uri = URI::Escape::EXPORT::DEFAULT::<&uri_escape>;

Be careful I<not> to put C<sub EXPORT> after L«C<unit> declarator|/syntax/unit».
If you do so, it'll become just a sub inside your package, rather than the
special export sub:

=for code :solo
unit module Bar;
sub EXPORT { Map.new: Foo => &say } # WRONG!!! Sub is scoped wrong

As explained in L<its definition|/language/modules#EXPORT>, C<sub EXPORT> is
part of the I<compunit>, not the package. So this would be the right way to
do it:

=for code :solo
sub EXPORT { Map.new: Foo => &say } # RIGHT!!! Sub is outside the module
unit module Bar;

=head2 Finding installed modules

It is up to the module installer to know where C<compunit> expects modules to be
placed. There will be a location provided by the
L<distribution|/routine/distribution> and in the current home directory. In
any case, letting the module installer deal with your modules is a safe bet.

=begin code :lang<shell>
cd your-module-dir
zef --force install .
=end code

X<|use lib>
A user may have a collection of modules not found in the normal ecosystem,
maintained by a module or package manager, but needed regularly.  Instead of
using the C<use lib> L<pragma|/language/pragmas#index-entry-lib__pragma> one
can use the C<RAKULIB> environment variable to point to module locations.
For example:

=for code :lang<shell>
export RAKULIB=/path/to/my-modules,/path/to/more/modules

Note that the comma (',') is used as the directory separator.

The directories in the C<RAKULIB> path will be searched for modules when
Raku C<need>s, C<use>s or C<require>s them. Directories that start with a
dot are ignored and symlinks are followed.

=head1 Testing modules and a distribution

It is important in this section to repeat the note at the beginning of this
document, namely that there is a difference between a B<Raku> C<distribution>,
which approximates a I<module> in other languages, and a B<Raku>
L<module declaration|https://docs.raku.org/language/syntax#index-entry-declarator_unit-declarator_module-declarator_package-Package,_Module,_Class,_Role,_and_Grammar_declaration>.
The reason for this is that a single file may contain a number of C<class>,
C<module>, C<role> etc declarations, or these declarations may be spread between
different files. In addition, when a C<distribution> is published (see
L<Distributing modules|/language/modules#Distributing_modules>) it may be
necessary to provide access to other resources, such as callable utilities.

B<Raku> also allows for a single distribution to provide multiple C<compunit>s
that can be C<use>d (or C<require>d etc). The information about a distribution
is contained in the C<META6.json> file in the distribution's root directory. See
below for more about C<META6.json>. Each entity that the B<distribution> allows
to be C<use>d (or C<require>d etc), also called a C<compunit>, is placed in the
C<provides> section of the C<META6.json> (as specified below).

It should also be noted that when writing the C<depends> section of the
C<META6.json> file, it is the name of the B<distribution> that is listed, not
the name of the C<compunit> that is desired. Although, for very many entities,
the name of the I<distribution> and the name of the I<compunit> are the same.
Another global effect of the C<depends> list in a distribution made available to
the Ecosystem, is that package managers, e.g. C<zef>, can look for C<compunit>
names in all distributions available.

Given this arrangement, the B<rakudo> compiler, or a package manager such as
B<zef>, can obtain all the information needed about each C<compunit> from a
C<META6.json> file in a directory.

This also means that a testing program such as B<Perl>'s C<prove> or the B<Raku>
equivalent L<prove6|https://modules.raku.org/dist/App::Prove6:cpan:LEONT> can be
run in the root directory of the B<distribution> as, e.g.,

=for code :lang<shell>
prove -e 'raku -I.'

or

=for code :lang<shell>
prove6 -I.

In both cases, the testing program looks for a directory C<t/> and runs the test
programs there (see L<Testing|/language/testing>).

The parameter B<-I.>, rather than B<-Ilib>, in the examples above is significant
because then the compiler will inspect the C<META6.json> file in the root
directory of the B<distribution>.

If you are just beginning to develop a module (or series of modules), and you
have not decided what to call or where to place the code (perhaps splitting it
into several C<*.rakumod> files), but assuming all the module files are under
the C<lib/> directory, then it is possible to use

=for code :lang<shell>
prove6 -Ilib

This is deceptive. A distribution may pass all the tests based on local files,
and it may pass release steps, but the distribution (and the
modules/classes/roles it contains) may not be automatically installed. To give a
common example, but not the only way this problem can manifest itself, if the
distribution is listed in the C<depends> section of another distribution, and a
user is trying to install the other distribution using C<zef> (or a package
manager using the same testing regime), perhaps using a CLI command C<zef
install --deps-only .>, then C<zef> arranges for the tests of the dependent
modules based on B<-I.> and not C<-Ilib>. This will lead to B<rakudo> errors
complaining about the absence of named B<compunits> unless the B<META6.json>
file is correct.

The most basic test that should be run for each C<compunit> that is defined for
the distribution is

=for code :preamble<use Test>
use-ok 'MyModule';

assuming inside C<META6.json> there is a line such as

=for code :lang<json>
depends: [ "MyModule": "lib/MyModule.rakumod" ],

It is also highly recommended to use the C<Test::META> C<meta-ok> test, which
verifies the validity of the C<META6.json> file. If you wish to add a
distribution (module) to the C<Ecosystem>, then this test will be applied to the
distribution.

Since C<meta-ok> only needs to be tested by the developer/maintainer of a
module, it can be within a set of extended tests in another directory, e.g.
C</xt>. This is because C<prove6>, for example, only runs the tests in C<t/> by
default. Then to run the extended tests:

=for code :lang<shell>
prove6 -I. xt/

Indeed it is becoming common practice by B<Raku> community developers to place
the extensive testing of a distribution in C<xt/> and to put minimal I<sanity>
tests in C<t/>. Extensive testing is essential for development and quality
control, but it can slow down the installation of popular distributions.

An alternative to placing the C<meta-ok> test in an extended test directory, but
to ensure that it is only run when a developer or maintainer wants to, is to
make the test dependent on an environment variable, e.g., in
C<t/99-author-test.t> there is the following code

=begin code
use Test;

plan 1;

if ?%*ENV<AUTHOR_TESTING> {
    require Test::META <&meta-ok>;
    meta-ok;
    done-testing;
} else {
    skip-rest "Skipping author test";
    exit;
}
=end code

Then when testing the module by the developer, use

=for code :lang<shell>
    AUTHOR_TEST=1 prove6 -I.

=head1 Distributing modules

If you've written a Raku module and would like to share it with the
community, we'd be delighted to have it listed in the
L<Raku modules directory|https://modules.raku.org>. C<:)>

Currently, there are three ways to distribute a module. No matter which method
you choose, your module will be indexed on the L<raku.land|https://raku.land>
and L<modules.raku.org|https://modules.raku.org> websites. The three module
distribution networks, or ecosystems, are:

=item B<CPAN>
This is the same ecosystem Perl is using. Modules are uploaded as I<.zip>
or I<.tar.gz> files on L<PAUSE|https://pause.perl.org/>.

=item B<zef ecosystem> using the C<fez> utility Use of the C<fez> command is
the newest and perhaps easiest way to distribute your module and is growing in
popularity.

=item B<p6c>
Up until recently the only ecosystem. It is based
on Github repositories which are directly accessed. It has only limited
capability for versioning.

The process of sharing your module consists of two steps, preparing the module
and uploading the module to one of the ecosystems mentioned above. More details
on the two steps are below.

=head2 Preparing the module

For a module to work in any of the ecosystems, it needs to follow a certain
structure. Here is how to do that:

=item Create a project directory named after your module. For
    example, if your module is C<Vortex::TotalPerspective>, then create a
    project directory named C<Vortex-TotalPerspective>.

=begin item
Make your project directory look like this:

=begin code :lang<text>
Vortex-TotalPerspective/
├── lib
│   └── Vortex
│       └── TotalPerspective.rakumod
├── LICENSE
├── META6.json
├── README.md
└── bin
│    └── vortex
└── t
    └── basic.t
=end code

If your project contains other modules that help the main module do
its job, they should go in your lib directory like so:

=begin code :lang<text>
lib
└── Vortex
    ├── TotalPerspective.rakumod
    └── TotalPerspective
        ├── FairyCake.rakumod
        └── Gargravarr.rakumod
=end code
=end item

=begin item

If you have any additional files (such as templates or a dynamic
library) that you wish to have installed so you can access them at
runtime, they should be placed in a C<resources> subdirectory of your project, e.g.:

=begin code :lang<text>
resources
└── templates
        └── default-template.mustache
=end code

The file must then be referenced in C<META6.json> (see below for more on
C<META6.json>) so that the distribution path can be provided to the program.

=begin code :lang<javascript>
{
    "name" : "Vortex::TotalPerspective",
    "provides" : {
        "Vortex::TotalPerspective" : "lib/Vortex/TotalPerspective.rakumod"
    },
    "resources": [ "templates/default-template.mustache"]
}
=end code

The additional file can then be accessed inside module code:
=begin code
my $template-text = %?RESOURCES<templates/default-template.mustache>.slurp;
# Note that %?RESOURCES provides a C<IO> path object
=end code

=end item

=item Programs and scripts that you need in the C<$PATH> for execution need
to be
included in the C<bin> directory; these will be copied to whatever directory
your installed Rakudo distribution has allotted for executables; could be
something like C<~/.rakubrew/shims/> (if you use the excellent
C<App::Rakubrew> for them)

=item The C<README.md> file is a
L<markdown-formatted|https://help.github.com/articles/markdown-basics/>
text file, which will later be automatically rendered as HTML by GitHub/GitLab for modules kept
in those ecosystems or by L<modules.raku.org|https://modules.raku.org> website for modules
kept on L<CPAN|/language/faq#index-entry-CPAN_(FAQ)>.

=item Regarding the C<LICENSE> file, if you have no other preference,
you might just use the same one that Rakudo Raku uses. Just
copy/paste the raw form of L<its license|https://github.com/rakudo/rakudo/blob/master/LICENSE>
into your own C<LICENSE> file.

=item The license field in META6.json
should be one of the standardized names listed here:
L<https://spdx.org/licenses/>. In the case of the B<Artistic 2.0> license, which
    is what many of our ecosystem modules use, its identifier is
    C<Artistic-2.0>. Having standardized identifiers make it easy for humans
    and computers alike to know which license was actually used by looking at
    the metadata!

=item If you can't find your license on C<spdx.org> or you use your own license,
you should put the license's name in the license field. For more details see
L<https://design.raku.org/S22.html#license>.

=item If you don't yet have any tests, you can leave out the C<t>
directory and C<basic.t> file for now. For more information on how to write
tests (for now), you might have a look at how other modules use
C<Test>.

=begin item

To document your modules, use L<Raku Pod |/language/pod> markup inside them.
Module documentation is most appreciated and will be especially important once
the Raku module directory (or some other site) begins rendering Pod docs as
HTML for easy browsing. If you have extra docs (in addition to the Pod docs in
your module(s)), create a C<doc> directory for them. Follow the same folder
structure as the C<lib> directory like so:

=begin code :lang<text>
doc
└── Vortex
    └── TotalPerspective.pod6
=end code
N<Note, described above is a minimal project directory. If your project
contains scripts that you'd like distributed along with your module(s),
put them in a C<bin> directory. If you'd like a graphical logo to
appear next to your module at the module directory, create a
C<logotype> directory and put into it a C<logo_32x32.png> file. At some
point, you might also consider adding C<CONTRIBUTORS>, C<NEWS>,
C<TODO>, or other files.>

If your module requires extra processing during installation to fully
integrate with and use non-Raku operating system resources, you may
need to add a X<C<Build.pm6>|Build.pm6> file (a "build hook") to the top-level directory. It will
be used by the C<zef> installer as the first step in the installation process.
See the README for C<zef> for a brief example. Also see various usage scenarios in existing
ecosystem modules such as C<zef> itself.
=end item

=begin item

Make your X<C<META6.json>|META6.json> file look something like this:

=begin code :allow<R> :lang<javascript>
{
    "perl" : "6.c",
    "name" : "Vortex::TotalPerspective",
    "api"  : "1",
    "auth" : "github:SomeAuthor",
    "version" : "0.0.1",
    "description" : "Wonderful simulation to get some perspective.",
    "authors" : [ "R<Your Name>" ],
    "license" : "Artistic-2.0",
    "provides" : {
        "Vortex::TotalPerspective" : "lib/Vortex/TotalPerspective.rakumod"
    },
    "depends" : [ ],
    "build-depends" : [ ],
    "test-depends" : [ ],
    "resources" : [ ],
    "tags": [
      "Vortex", "Total", "Perspective"
    ],
    "source-url" : "git://github.com/R<you>/Vortex-TotalPerspective.git"
}
=end code

The attributes in this file are analyzed by the
L<C<META6>|https://github.com/jonathanstowe/META6> class. They are divided into
optional, mandatory and I<customary>. Mandatory are the ones you need to insert
into your file, and customary are those used by the current Raku ecosystem and
possibly displayed on the module page if it's published, but you have no
obligation to use it.

For choosing a version numbering scheme, try and use "major.minor.patch" (see
L<the spec on versioning|https://design.raku.org/S11.html#Versioning> for
further details). This will go into the C<version> key of C<META6.json>. This
field is optional, but used by installation to match against installed version,
if one exists. The C<description> field is also mandatory, and includes a short
description of the module.

The C<name> key is compulsory, and C<zef> will fail if you do not include it.
Even if you have created a META6.json file just to express the dependencies
for a series of scripts, this section must be included.

Optionally, you can set an C<api> field. Incrementing this indicates
that the interface provided by your module is not backwards compatible
with a previous version. You can use it if you want to adhere to
L<Semantic Versioning|https://semver.org>. A best practice is to simply
keep the C<api> field to the same value as your major version number. A
dependency can then depend on your module by including a C<:api> part,
which will ensure backwards incompatible releases will not be pulled in.

The C<auth> section identifies the author in GitHub or other repository
hosting site, such as Bitbucket or GitLab. This field is I<customary>,
since it's used to identify the author in the ecosystem, and opens the
possibility of having modules with the same name and different authors.

The C<authors> section includes a list of all the module authors. In
the case there is only one author, a single element list must be
supplied. This field is optional.

In the C<provides> section, include all the namespaces provided by your
distribution and that you wish to be installed; only module files that are
explicitly included here will be installed and available with C<use> or
C<require> in other programs. This field is mandatory.

Set C<perl> version to the minimum Raku version your module works with. This
field is mandatory. Use C<6.c> if your module is valid for Christmas release and
newer ones, use C<6.d> if it requires, at least, the Diwali version.

The C<resources> section is optional, but, if present, should contain a list
of the files in your C<resources> directory that you wish to be installed.
These will be installed with hashed names alongside your library files.
Their installed location can be determined through the C<%?RESOURCES> C<Hash>
indexed on the name provided. The C<tags> section is also optional. It is used to describe
the module in the Raku ecosystem.

The C<depends>, C<build-depends>, and C<test-depends> sections include different modules that
are used in those phases of the of installation. All are optional, but
they must obviously contain the modules that are going to be needed in those
particular phases. These dependencies might optionally use
L<C<Version>|/type/Version> specification strings; C<zef> will check for the
presence and versions of these modules and install or upgrade them if needed.

=for code :lang<JSON>
//...
"depends": [
       "URI",
       "File::Temp",
       "JSON::Fast",
       "Pod::To::BigPage:ver<0.5.0+>",
       "Pod::To::HTML:ver<0.6.1+>",
       "OO::Monitors",
       "File::Find",
       "Test::META"
],
//...

Additionally, C<depends> can be either an array as above or a hash that uses two
keys, C<runtime> and C<build>, whose function should be self-descriptive, and
which are used, for instance,
L<in C<Inline::Python>|https://github.com/niner/Inline-Python/blob/master/META6.json>:

=for code :lang<JSON>
//...
"depends" : {
        "build": {
            "requires": [
                "Distribution::Builder::MakeFromJSON",
                {
                    "from" : "bin",
                    "name" : {
                        "by-distro.name" : {
                            "macosx" : "python2.7-config",
                            "debian" : "python2.7-config",
                            "" : "python2-config"
                        }
                    }
                }
            ]
        },
        "runtime": {
            "requires": [
                "python2.7:from<native>"
            ]
        }
}, // ...

In general, the array form will be more than enough for most cases.

Finally, C<source-url> indicates the URL of the repository where the module is
developed; this is one of the customary modules if you are going to publish it
in the module ecosystem. The current module ecosystem will link this URL from
the project description. N<Some old modules also provide a C<source-type> field,
which was used to indicate the kind of source control system, generally C<git>,
which can be used to download the module. However, this field is nowadays
ignored by C<zef> and the rest of the tools.>

The L<C<Test::META> module | https://github.com/jonathanstowe/Test-META/> can
help
you check the correctness of the META6.json file; this module will check for all
the mandatory fields and that the type used for all of them is correct.

There are more fields described in the
L<C<META> design documents |https://design.raku.org/S22.html#META6.json>,
but not all of these are
implemented by existing package managers. Hence you should stick to the fields
described in the above example block to ensure compatibility with existing
package managers such as C<zef>. You can also check
L<Moritz Lenz's repository of all modules for examples|https://github.com/moritz/perl6-all-modules/search?l=JSON&q=META6.json&type=>,
but bear in mind that some of them might use fields, such as C<source-type>
above, which are currently ignored.

=end item

=begin item
If you want to test your module you can use the following command to install the
module directly from the module folder you just created.

=begin code :lang<shell>
zef install ./your-module-folder
=end code

Note that doing so precompiles and installs your module. If you make changes to
the source, you'll need to re-install the module.
(See C<use lib> L<pragma|/language/pragmas#index-entry-lib__pragma>, C<-I>
command line switch, or C<RAKULIB> env variable, to include a path to your
module source while developing it, so you don't have to install it at all).

=end item

=head2 Upload your module to CPAN

A prerequisite for using CPAN is a L<PAUSE|https://pause.perl.org/>
user account. If you don't have an account already, you can create one
L<here|https://pause.perl.org/pause/query?ACTION=request_id>
The process takes about 5 minutes and some e-mail back and forth.

=begin item
Create a package of your module:

=begin code :lang<shell>
cd your-module-folder
tar czf Vortex-TotalPerspective-0.0.1.tar.gz \
  --transform s/^\./Vortex-TotalPerspective-0.0.1/ --exclude-vcs\
  --exclude=.[^/]*
=end code

If you use git you can also use the following command to create a package
directly for a given commit.

=begin code :lang<shell>
git archive --prefix=Vortex-TotalPerspective-0.0.1/ \
  -o ../Vortex-TotalPerspective-0.0.1.tar.gz HEAD
=end code

=end item

=item Go to L<PAUSE|https://pause.perl.org/>, log in and navigate to
C<Upload a file to CPAN>.

=item Make sure you select C<Perl6> as the I<Target Directory>. For
    your first upload, you have to enter the string C<Perl6> in the text field.
    On subsequent uploads, you can select the C<Perl6> directory from the
    selection box right below the input field.

=begin item
Select your file and click I<Upload>! If everything was fine with your
dist, you should see your module tar file in your C<Perl6> directory along
with both a C<META> and a C<README> file named after your module filename.

I<Make sure you have a META6.json file in your dist and that the dist
version you're uploading is higher than the currently uploaded version.
Those are the most common upload errors.>

=end item

=head2 Upload your module to zef ecosystem

If you want to use the I<zef> ecosystem then you need to register your username
using I<fez>.

=item Install fez if you haven't done so already

=begin code :lang<shell>
zef install fez
=end code

=item Register your user with zef's ecosystem

=begin code :lang<shell>
fez register
>>= Email: your@email.com
>>= Username: username
>>= Password:
>>= registration successful, requesting auth key
>>= login successful, you can now upload dists
=end code

=item Now you can upload your module!

Before doing the following, ensure your C<META6.json> file's "auth" matches "zef:<username>" and then:

=begin code :lang<shell>
fez upload
>>= Vortex::TotalPerspective:ver<0.1.2>:auth<zef:username> looks OK
>>= Hey! You did it! Your dist will be indexed shortly
=end code

=head2 Upload your module to p6c

If you want to use the I<p6c> ecosystem you need to use git for your module's
version control. The instructions herein assume that you have a
L<GitHub|https://github.com> account so that your module can be shared from its
GitHub repository, however another provider such as
L<GitLab|https://about.gitlab.com/> should work as long as it works in a
similar way.

=item Put your project under git version control if you haven't done so
already.

=item Once you're happy with your project, create a repository for it on GitHub.
See L<GitHub's help docs|https://help.github.com/> if necessary. Your
GitHub repository should be named the same as your project directory. Immediately
after creating the GitHub repo, GitHub shows you how to configure your
local repository to know about your GitHub repository.

=item Push your project to GitHub.

=item Consider setting up automated testing (see L<https://docs.travis-ci.com/user/languages/perl6>).

=item Create a PR (Pull Request) on L<ecosystem|https://github.com/Raku/ecosystem> adding
your module to META.list, or ping someone on IRC (#raku at libera.chat) to
get help having it added.

=item After the pull request has been accepted, wait for an hour. If
your module doesn't show up on L<https://modules.raku.org/>, please
view the log file at L<https://modules.raku.org/update.log> to see
if it identifies an error with your module or C<meta> file.

B<That's it! Thanks for contributing to the Raku community!>

If you'd like to try out installing your module, use the X<zef> module
installer tool which is included with Rakudo Star Raku:

=begin code :lang<shell>
zef install Vortex::TotalPerspective
=end code

This will download your module to its own working directory (C<~/.zef>),
build it there, and install the module into your local Raku installation
directory.

To use C<Vortex::TotalPerspective> from your scripts, just write
C<use Vortex::TotalPerspective>, and your Raku implementation will
know where to look for the module file(s).

=head1 Modules and tools related to module authoring

You can find a list of modules and tools that aim to improve the experience of
writing/test modules at L<Modules Extra|/language/modules-extra>

=head2 Contact information

To discuss module development in general, or if your module would
fill a need in the ecosystem, naming, etc., you can use the
L<#raku on irc.libera.chat|irc://irc.libera.chat/#raku> IRC channel.

To discuss toolchain specific questions, you can use the
L<#raku-toolchain on irc.libera.chat|irc://irc.libera.chat/#raku-toolchain>
IRC channel. A repository to discuss tooling issues is also available at
L<https://github.com/Raku/toolchain-bikeshed>.

=end pod

# vim: expandtab softtabstop=4 shiftwidth=4 ft=perl6
